home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 July / EnigmA AMIGA RUN 20 (1997)(G.R. Edizioni)(IT)[!][issue 1997-07 & 08][EAR-CD IV].iso / earcd / text / misc / nroff.lha / nroff / text.c < prev    next >
C/C++ Source or Header  |  1997-02-11  |  14KB  |  942 lines

  1. #undef OLD_WAY
  2. /*
  3.  *    text.c - text output processing portion of nroff word processor
  4.  *
  5.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  6.  *    net:    rosenkra@hall.cray.com
  7.  *    CIS:    71460,17
  8.  *    GENIE:    W.ROSENKRANZ
  9.  *
  10.  *    original author:
  11.  *
  12.  *    Stephen L. Browning
  13.  *    5723 North Parker Avenue
  14.  *    Indianapolis, Indiana 46220
  15.  *
  16.  *    history:
  17.  *
  18.  *    - Originally written in BDS C;
  19.  *    - Adapted for standard C by W. N. Paul
  20.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  21.  */
  22.  
  23. #undef NRO_MAIN                    /* extern globals */
  24.  
  25. #include <stdio.h>
  26. #include "nroff.h"
  27.  
  28.  
  29. /*------------------------------*/
  30. /*    text            */
  31. /*------------------------------*/
  32. text (p)
  33. register char  *p;
  34. {
  35.  
  36. /*
  37.  *    main text processing
  38.  */
  39.  
  40.     register int    i;
  41.     char        wrdbuf[MAXLINE];
  42.  
  43.  
  44.     /*
  45.      *   skip over leading blanks if in fill mode. we indent later.
  46.      *   since leadbl does a robrk, do it if in .nf mode
  47.      */
  48.     if (dc.fill == YES)
  49.     {
  50.         if (*p == ' ' || *p == '\n' || *p == '\r')
  51.             leadbl (p);
  52.     }
  53.     else
  54.         robrk ();
  55.  
  56.  
  57.     /*
  58.      *   expand escape sequences
  59.      */
  60.     expesc (p, wrdbuf);
  61.  
  62.  
  63.     /*
  64.      *   test for how to output
  65.      */
  66.     if (dc.ulval > 0)
  67.     {
  68.         /*
  69.          *   underline (.ul)
  70.          *
  71.          *   Because of the way underlining is handled,
  72.          *   MAXLINE should be declared to be three times
  73.          *   larger than the longest expected input line
  74.          *   for underlining.  Since many of the character
  75.          *   buffers use this parameter, a lot of memory
  76.          *   can be allocated when it may not really be
  77.          *   needed.  A MAXLINE of 180 would allow about
  78.          *   60 characters in the output line to be
  79.          *   underlined (remember that only alphanumerics
  80.          *   get underlined - no spaces or punctuation).
  81.          */
  82.         underl (p, wrdbuf, MAXLINE);
  83.         --dc.ulval;
  84.     }
  85.     if (dc.cuval > 0)
  86.     {
  87.         /*
  88.          *   continuous underline (.cu)
  89.          */
  90.         underl (p, wrdbuf, MAXLINE);
  91.         --dc.cuval;
  92.     }
  93.     if (dc.boval > 0)
  94.     {
  95.         /*
  96.          *   bold (.bo)
  97.          */
  98.         bold (p, wrdbuf, MAXLINE);
  99.         --dc.boval;
  100.     }
  101.     if (dc.ceval > 0)
  102.     {
  103.         /*
  104.          *   centered (.ce)
  105.          */
  106.         center (p);
  107.         do_mc (p);
  108.         put (p);
  109.         --dc.ceval;
  110.     }
  111.     else if ((*p == '\r' || *p == '\n') && dc.fill == NO)
  112.     {
  113.         /*
  114.          *   all blank line
  115.          */
  116.         do_mc (p);
  117.         put (p);
  118.     }
  119.     else if (dc.fill == NO)
  120.     {
  121.         /*
  122.          *   unfilled (.nf)
  123.          */
  124.         do_mc (p);
  125.         put (p);
  126.     }
  127.     else
  128.     {
  129.         /*
  130.          *   anything else...
  131.          *
  132.          *   init escape char counter for this line...
  133.          */
  134. /*        co.outesc = 0;*/
  135.  
  136.  
  137.         /*
  138.          *   get a word and put it out. increment ptr to the next
  139.          *   word.
  140.          */
  141.         while ((i = getwrd (p, wrdbuf)) > 0)
  142.         {
  143. /*            co.outesc += countesc (wrdbuf);*/
  144.  
  145.             putwrd (wrdbuf);
  146.             p += i;
  147.         }
  148.     }
  149. }
  150.  
  151.  
  152.  
  153.  
  154. /*------------------------------*/
  155. /*    bold            */
  156. /*------------------------------*/
  157. bold (p0, p1, size)
  158. register char  *p0;
  159. register char  *p1;
  160. int        size;
  161. {
  162.  
  163. /*
  164.  *    insert bold face text (by overstriking)
  165.  */
  166.  
  167.     register int    i;
  168.     register int    j;
  169.  
  170.     j = 0;
  171.     for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i)
  172.     {
  173.         if (isalpha (p0[i]) || isdigit (p0[i]))
  174.         {
  175.             p1[j++] = p0[i];
  176.             p1[j++] = '\b';
  177.         }
  178.         p1[j++] = p0[i];
  179.     }
  180.     p1[j++] = '\n';
  181.     p1[j] = EOS;
  182.     while (*p1 != EOS)
  183.         *p0++ = *p1++;
  184.     *p0 = EOS;
  185. }
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192. /*------------------------------*/
  193. /*    center            */
  194. /*------------------------------*/
  195. center (p)
  196. register char  *p;
  197. {
  198.  
  199. /*
  200.  *    center a line by setting tival
  201.  */
  202.  
  203.     dc.tival = max ((dc.rmval + dc.tival - width (p)) >> 1, 0);
  204. }
  205.  
  206.  
  207.  
  208.  
  209. /*------------------------------*/
  210. /*    expand            */
  211. /*------------------------------*/
  212. expand (p0, c, s)
  213. register char  *p0;
  214. char        c;
  215. register char  *s;
  216. {
  217.  
  218. /*
  219.  *    expand title buffer to include character string
  220.  */
  221.  
  222.     register char  *p;
  223.     register char  *q;
  224.     register char  *r;
  225.     char        tmp[MAXLINE];
  226.  
  227.     p = p0;
  228.     q = tmp;
  229.     while (*p != EOS)
  230.     {
  231.         if (*p == c)
  232.         {
  233.             r = s;
  234.             while (*r != EOS)
  235.                 *q++ = *r++;
  236.         }
  237.         else
  238.             *q++ = *p;
  239.         ++p;
  240.     }
  241.     *q = EOS;
  242.     strcpy (p0, tmp);        /* copy it back */
  243. }
  244.  
  245.  
  246.  
  247.  
  248. /*------------------------------*/
  249. /*    justcntr        */
  250. /*------------------------------*/
  251. justcntr (p, q, limit)
  252. register char  *p;
  253. char           *q;
  254. int           *limit;
  255. {
  256.  
  257. /*
  258.  *    center title text into print buffer
  259.  */
  260.  
  261.     register int    len;
  262.  
  263.     len = width (p);
  264.     q   = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
  265.     while (*p != EOS)
  266.         *q++ = *p++;
  267. }
  268.  
  269.  
  270.  
  271.  
  272.  
  273. /*------------------------------*/
  274. /*    justleft        */
  275. /*------------------------------*/
  276. justleft (p, q, limit)
  277. register char  *p;
  278. char           *q;
  279. int        limit;
  280. {
  281.  
  282. /*
  283.  *    left justify title text into print buffer
  284.  */
  285.  
  286.     q = &q[limit];
  287.     while (*p != EOS)
  288.         *q++ = *p++;
  289. }
  290.  
  291.  
  292.  
  293.  
  294. /*------------------------------*/
  295. /*    justrite        */
  296. /*------------------------------*/
  297. justrite (p, q, limit)
  298. register char  *p;
  299. char           *q;
  300. int         limit;
  301. {
  302.  
  303. /*
  304.  *    right justify title text into print buffer
  305.  */
  306.  
  307.     register int    len;
  308.  
  309.     len = width (p);
  310.     q = &q[limit - len];
  311.     while (*p != EOS)
  312.         *q++ = *p++;
  313. }
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320. /*------------------------------*/
  321. /*    leadbl            */
  322. /*------------------------------*/
  323. leadbl (p)
  324. register char  *p;
  325. {
  326.  
  327. /*
  328.  *    delete leading blanks, set tival
  329.  */
  330.  
  331.     register int    i;
  332.     register int    j;
  333.  
  334.     /*
  335.      *   end current line and reset co struct
  336.      */
  337.     robrk ();
  338.  
  339.     /*
  340.      *   skip spaces
  341.      */
  342.     for (i = 0; p[i] == ' ' || p[i] == '\t'; ++i)
  343.         ;
  344.  
  345.     /*
  346.      *   if not end of line, reset current temp indent
  347.      */
  348.     if (p[i] != '\n' && p[i] != '\r')
  349.         dc.tival = i;
  350.  
  351.     /*
  352.      *   shift string
  353.      */
  354.     for (j = 0; p[i] != EOS; ++j)
  355.         p[j] = p[i++];
  356.     p[j] = EOS;
  357. }
  358.  
  359.  
  360.  
  361.  
  362.  
  363. /*------------------------------*/
  364. /*    pfoot            */
  365. /*------------------------------*/
  366. pfoot ()
  367. {
  368.  
  369. /*
  370.  *    put out page footer
  371.  */
  372.  
  373.     if (dc.prflg == TRUE)
  374.     {
  375.         skip (pg.m3val);
  376.         if (pg.m4val > 0)
  377.         {
  378.             if ((pg.curpag % 2) == 0)
  379.             {
  380.                 puttl (pg.efoot, pg.eflim, pg.curpag);
  381.             }
  382.             else
  383.             {
  384.                 puttl (pg.ofoot, pg.oflim, pg.curpag);
  385.             }
  386.             skip (pg.m4val - 1);
  387.         }
  388.     }
  389. }
  390.  
  391.  
  392.  
  393.  
  394.  
  395. /*------------------------------*/
  396. /*    phead            */
  397. /*------------------------------*/
  398. phead ()
  399. {
  400.  
  401. /*
  402.  *    put out page header
  403.  */
  404.  
  405.     pg.curpag = pg.newpag;
  406.     if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg)
  407.     {
  408.         dc.prflg = TRUE;
  409.     }
  410.     else
  411.     {
  412.         dc.prflg = FALSE;
  413.     }
  414.     ++pg.newpag;
  415.     set_ireg ("%", pg.newpag, 0);
  416.     if (dc.prflg == TRUE)
  417.     {
  418.         if (pg.m1val > 0)
  419.         {
  420.             skip (pg.m1val - 1);
  421.             if ((pg.curpag % 2) == 0)
  422.             {
  423.                 puttl (pg.ehead, pg.ehlim, pg.curpag);
  424.             }
  425.             else
  426.             {
  427.                 puttl (pg.ohead, pg.ohlim, pg.curpag);
  428.             }
  429.         }
  430.         skip (pg.m2val);
  431.     }
  432.     /* 
  433.      *    initialize lineno for the next page
  434.      */
  435.     pg.lineno = pg.m1val + pg.m2val + 1;
  436.     set_ireg ("ln", pg.lineno, 0);
  437. }
  438.  
  439.  
  440.  
  441.  
  442. /*------------------------------*/
  443. /*    puttl            */
  444. /*------------------------------*/
  445. puttl (p, lim, pgno)
  446. register char  *p;
  447. int           *lim;
  448. int        pgno;
  449. {
  450.  
  451. /*
  452.  *    put out title or footer
  453.  */
  454.  
  455.     register int    i;
  456.     char        pn[8];
  457.     char        t[MAXLINE];
  458.     char        h[MAXLINE];
  459.     char        delim;
  460.  
  461.     itoda (pgno, pn, 6);
  462.     for (i = 0; i < MAXLINE; ++i)
  463.         h[i] = ' ';
  464.     delim = *p++;
  465.     p = getfield (p, t, delim);
  466.     expand (t, dc.pgchr, pn);
  467.     justleft (t, h, lim[LEFT]);
  468.     p = getfield (p, t, delim);
  469.     expand (t, dc.pgchr, pn);
  470.     justcntr (t, h, lim);
  471.     p = getfield (p, t, delim);
  472.     expand (t, dc.pgchr, pn);
  473.     justrite (t, h, lim[RIGHT]);
  474.     for (i = MAXLINE - 4; h[i] == ' '; --i)
  475.         h[i] = EOS;
  476.     h[++i] = '\n';
  477. #ifndef NOCR
  478.     h[++i] = '\r';
  479. #endif
  480.     h[++i] = EOS;
  481.     if (strlen (h) > 2)
  482.     {
  483.         for (i = 0; i < pg.offset; ++i)
  484.             prchar (' ', out_stream);
  485.     }
  486.     putlin (h, out_stream);
  487. }
  488.  
  489.  
  490.  
  491.  
  492.  
  493. /*------------------------------*/
  494. /*    putwrd            */
  495. /*------------------------------*/
  496. putwrd (wrdbuf)
  497. register char  *wrdbuf;
  498. {
  499.  
  500. /*
  501.  *    put word in output buffer
  502.  */
  503.  
  504.     register char  *p0;
  505.     register char  *p1;
  506.     int         w;
  507.     int         last;
  508.     int         llval;
  509.     int         nextra;
  510.  
  511.  
  512.  
  513.     /*
  514.      *   check if this word puts us over the limit
  515.      */
  516.     w     = width (wrdbuf);
  517.     last  = strlen (wrdbuf) + co.outp;
  518.     llval = dc.rmval - dc.tival;
  519. /*    if (((co.outp > 0) && ((co.outw + w) > llval))*/
  520.     co.outesc += countesc (wrdbuf);
  521.     if (((co.outp > 0) && ((co.outw + w - co.outesc) > llval))
  522.     ||   (last > MAXLINE))
  523.     {
  524.         /*
  525.          *   last word exceeds limit so prepare to break line, print
  526.          *   it, and reset outbuf.
  527.          */
  528.         last -= co.outp;
  529.         if (dc.juval == YES)
  530.         {
  531.             nextra = llval - co.outw + 1;
  532.  
  533.             /*
  534.              *      Do not take in the escape char of the
  535.              *      word that didn't fit on this line anymore
  536.              */
  537.              co.outesc -= countesc (wrdbuf);
  538.  
  539.             /* 
  540.              *    Check whether last word was end of
  541.              *    sentence and modify counts so that
  542.              *    it is right justified.
  543.              */
  544.             if (co.outbuf[co.outp - 2] == ' ')
  545.             {
  546.                 --co.outp;
  547.                 ++nextra;
  548.             }
  549. #ifdef OLD_WAY
  550.             spread (co.outbuf, co.outp - 1, nextra, co.outwds, co.outesc);
  551.             if ((nextra > 0) && (co.outwds > 1))
  552.             {
  553.                 co.outp += (nextra - 1);
  554.             }
  555. /*            if (co.outesc > 0)
  556.             {
  557.                 co.outp += co.outesc;
  558.             }
  559. */
  560. #else
  561.             spread (co.outbuf, co.outp - 1, nextra, 
  562.                         co.outwds, co.outesc);
  563.             if ((nextra + co.outesc > 0) && (co.outwds > 1))
  564.             {
  565.                 co.outp += (nextra + co.outesc - 1);
  566.             }
  567. #endif
  568.         }
  569.  
  570.         /*
  571.          *   break line, output it, and reset all co members. reset
  572.          *   esc count.
  573.          */
  574.         robrk ();
  575.  
  576.         co.outesc = countesc (wrdbuf);
  577.     }
  578.  
  579.  
  580.     /*
  581.      *   copy the current word to the out buffer which may have been
  582.      *   reset
  583.      */
  584.     p0 = wrdbuf;
  585.     p1 = co.outbuf + co.outp;
  586.     while (*p0 != EOS)
  587.         *p1++ = *p0++;
  588.  
  589.     co.outp              = last;
  590.     co.outbuf[co.outp++] = ' ';
  591.     co.outw             += w + 1;
  592.     co.outwds           += 1;
  593. }
  594.  
  595.  
  596.  
  597.  
  598. /*------------------------------*/
  599. /*    skip            */
  600. /*------------------------------*/
  601. skip (n)
  602. register int    n;
  603. {
  604.  
  605. /*
  606.  *    skips the number of lines specified by n.
  607.  */
  608.  
  609.     register int    i;
  610.     register int    j;
  611.  
  612.  
  613.     if (dc.prflg == TRUE && n > 0)
  614.     {
  615.         for (i = 0; i < n; ++i)
  616.         {
  617.             /*
  618.              *   handle blank line with changebar
  619.              */
  620.             if (mc_ing == TRUE)
  621.             {
  622.                 for (j = 0; j < pg.offset; ++j)
  623.                     prchar (' ', out_stream);
  624.                 for (j = 0; j < dc.rmval; ++j)
  625.                     prchar (' ', out_stream);
  626.                 for (j = 0; j < mc_space; j++)
  627.                     prchar (' ', out_stream);
  628.                 prchar (mc_char, out_stream);
  629.             }
  630.             prchar ('\n', out_stream);
  631. #ifndef NOCR
  632.             prchar ('\r', out_stream);
  633. #endif
  634.         }
  635.     }
  636. }
  637.  
  638.  
  639.  
  640.  
  641.  
  642. /*------------------------------*/
  643. /*    spread            */
  644. /*------------------------------*/
  645. spread (p, outp, nextra, outwds, escapes)
  646. register char  *p;
  647. int         outp;
  648. int        nextra;
  649. int        outwds;
  650. int        escapes;
  651. {
  652.  
  653. /*
  654.  *    spread words to justify right margin
  655.  */
  656.  
  657.     register int    i;
  658.     register int    j;
  659.     register int    nb;
  660.     register int    ne;
  661.     register int    nholes;
  662.     int        jmin;
  663.  
  664.  
  665.     /*
  666.      *   quick sanity check...
  667.      */
  668. #ifdef OLDWAY
  669.     if ((nextra <= 0) || (outwds <= 1))
  670.         return;
  671. #else
  672.     if ((nextra + escapes < 1) || (outwds < 2))
  673.         return;
  674. #endif
  675.  
  676.  
  677. /*fflush (out_stream); fprintf (err_stream, "in spread: escapes = %d\n", escapes); fflush (err_stream);*/
  678.  
  679.  
  680.     /*
  681.      *   set up for the spread and do it...
  682.      */
  683.     dc.sprdir = ~dc.sprdir;
  684. #ifdef OLD_WAY
  685.     ne        = nextra;
  686. #else
  687.     ne        = nextra + escapes;
  688. #endif
  689.     nholes    = outwds - 1;            /* holes between words */
  690.     i         = outp - 1;            /* last non-blank character */
  691.     j         = min (MAXLINE - 3, i + ne);    /* leave room for CR,LF,EOS */
  692. /*
  693.     j        += escapes;
  694.     if (p[i-1] == 27)
  695.         j += 2;
  696.     j = min (j, MAXLINE - 3);
  697. */
  698.     while (i < j)
  699.     {
  700.         p[j] = p[i];
  701.         if (p[i] == ' ')
  702.         {
  703.             if (dc.sprdir == 0)
  704.                 nb = (ne - 1) / nholes + 1;
  705.             else
  706.                 nb = ne / nholes;
  707.             ne -= nb;
  708.             --nholes;
  709.             for (; nb > 0; --nb)
  710.             {
  711.                 --j;
  712.                 p[j] = ' ';
  713.             }
  714.         }
  715.         --i;
  716.         --j;
  717.     }
  718. }
  719.  
  720.  
  721.  
  722.  
  723.  
  724. /*------------------------------*/
  725. /*    strkovr            */
  726. /*------------------------------*/
  727. strkovr (p, q)
  728. register char  *p;
  729. register char  *q;
  730. {
  731.  
  732. /*
  733.  *    split overstrikes (backspaces) into seperate buffer
  734.  */
  735.  
  736.     register char  *pp;
  737.     int        bsflg;
  738.  
  739.     bsflg = FALSE;
  740.     pp = p;
  741.     while (*p != EOS)
  742.     {
  743.         *q = ' ';
  744.         *pp = *p;
  745.         ++p;
  746.         if (*p == '\b')
  747.         {
  748.             if (*pp >= ' ' && *pp <= '~')
  749.             {
  750.                 bsflg = TRUE;
  751.                 *q = *pp;
  752.                 ++p;
  753.                 *pp = *p;
  754.                 ++p;
  755.             }
  756.         }
  757.         ++q;
  758.         ++pp;
  759.     }
  760.     *q++ = '\r';
  761.     *q = *pp = EOS;
  762.  
  763.     return (bsflg);
  764. }
  765.  
  766.  
  767.  
  768.  
  769.  
  770. /*------------------------------*/
  771. /*    underl            */
  772. /*------------------------------*/
  773. underl (p0, p1, size)
  774. register char  *p0;
  775. register char  *p1;
  776. int        size;
  777. {
  778.  
  779. /*
  780.  *    underline a line
  781.  */
  782.  
  783.     register int    i;
  784.     register int    j;
  785.  
  786.     j = 0;
  787.     for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i)
  788.     {
  789.         if (p0[i] >= ' ' && p0[i] <= '~')
  790.         {
  791.             if (isalpha (p0[i]) || isdigit (p0[i]) || dc.cuval > 0)
  792.             {
  793.                 p1[j++] = '_';
  794.                 p1[j++] = '\b';
  795.             }
  796.         }
  797.         p1[j++] = p0[i];
  798.     }
  799.     p1[j++] = '\n';
  800.     p1[j] = EOS;
  801.     while (*p1 != EOS)
  802.         *p0++ = *p1++;
  803.     *p0 = EOS;
  804. }
  805.  
  806.  
  807.  
  808.  
  809. /*------------------------------*/
  810. /*    width            */
  811. /*------------------------------*/
  812. width (s)
  813. register char  *s;
  814. {
  815.  
  816. /*
  817.  *    compute width of character string
  818.  */
  819.  
  820.     register int    w;
  821.  
  822.     w = 0;
  823.     while (*s != EOS)
  824.     {
  825.         if (*s == '\b')
  826.             --w;
  827.         else if (*s != '\n' && *s != '\r')
  828.             ++w;
  829.         ++s;
  830.     }
  831.  
  832.     return (w);
  833. }
  834.  
  835.  
  836.  
  837.  
  838. /*------------------------------*/
  839. /*    do_mc            */
  840. /*------------------------------*/
  841. do_mc (p)
  842. char   *p;
  843. {
  844.  
  845. /*
  846.  *    add margin char (change bar) for .nf and .ce lines.
  847.  *
  848.  *    filled lines handled in robrk(). blank lines (.sp) handled in skip().
  849.  *    note: robrk() calls this routine, too.
  850.  */
  851.  
  852.     register char  *ps;
  853.     register int    nspaces;
  854.     register int    i;
  855.     register int    has_cr;
  856.     register int    has_lf;
  857.     int        len;
  858.     int        nesc;
  859.  
  860.  
  861.     if (mc_ing == FALSE)
  862.         return;
  863.  
  864.  
  865.     len = strlen (p);
  866.  
  867.  
  868.     /*
  869.      *   get to the end...
  870.      */
  871.     ps = p;
  872.     while (*ps)
  873.         ps++;
  874.  
  875.  
  876.     /*
  877.      *   check for cr and lf
  878.      */
  879.     ps--;
  880.     has_lf = 0;
  881.     has_cr = 0;
  882.     while (ps >= p && (*ps == '\r' || *ps == '\n'))
  883.     {
  884.         if (*ps == '\n')
  885.             has_lf++;
  886.         else
  887.             has_cr++;
  888.  
  889.         len--;
  890.         ps--;
  891.     }
  892.     if (has_lf < has_cr)
  893.         has_lf = has_cr;
  894.     else if (has_cr < has_lf)
  895.         has_cr = has_lf;
  896.  
  897.  
  898.     /*
  899.      *   remove any trailing blanks here
  900.      */
  901.     while (ps >= p && *ps == ' ')
  902.     {
  903.         ps--;
  904.         len--;
  905.     }
  906.     *++ps = EOS;
  907.  
  908.  
  909.     /*
  910.      *   add trailing spaces for short lines. count escapes, subtract
  911.      *   from len. use rmval for rigth margin (minus tival which is
  912.      *   added later in put).
  913.      */
  914.     nesc    = countesc (p);
  915.     len    -= nesc;
  916.     nspaces = dc.rmval - dc.tival - len;
  917.     for (i = 0; i < nspaces; i++, ps++)
  918.         *ps = ' ';
  919.  
  920.  
  921.     /*
  922.      *   add the bar...
  923.      */
  924.     for (i = 0; i < mc_space; i++, ps++)
  925.         *ps = ' ';
  926.     *ps++ = mc_char;
  927.  
  928.  
  929.     /*
  930.      *   replace cr, lf, and EOS
  931.      */
  932.     while (has_lf--)
  933.     {
  934.         *ps++ = '\r';
  935.         *ps++ = '\n';
  936.     }
  937.     *ps = EOS;
  938.  
  939.  
  940.     return;
  941. }
  942.